package com.lyy.system.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lyy.Vo.UserEditVO;
import com.lyy.Vo.UserLogin;
import com.lyy.Vo.UserRole;
import com.lyy.config.JWTUtils;
import com.lyy.handler.BusinessException;
import com.lyy.response.ResultCode;
import com.lyy.system.entity.*;
import com.lyy.system.enums.UserStatusEnum;
import com.lyy.system.enums.UserTypeEnum;
import com.lyy.system.mapper.*;
import com.lyy.system.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lyy.utils.RedisUtil;
import org.omg.CORBA.SystemException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.function.Function;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author lyy
 * @since 2022-05-05
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private DepartmentMapper departmentMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private RedisUtil redisUtil;



    /**
     * 查询所有数据
     * @return
     */
    @Override
    public List<User> queryAll() {
        return this.baseMapper.queryAll();
    }

    /**
     * 条件分页查询数据
     * @param page
     * @param wrapper
     * @return
     */
    @Override
    public IPage<User> findUserPage(Page<User> page, QueryWrapper<User> wrapper) {
        return this.baseMapper.findUserPage(page,wrapper);
    }

    @Override
    public void addUser(User user) {
        //判断是否添加同一用户
        String username= user.getUsername();
        //获取部门
        Long departmentId=user.getDepartmentId();
        QueryWrapper<User> wrapper=new QueryWrapper<>();
        wrapper.eq("username",username);
        Integer count=this.baseMapper.selectCount(wrapper);
        if (count!=0){
            throw new BusinessException(ResultCode.USER_ACCOUNT_ALREADY_EXIST.getCode(),
                    ResultCode.USER_ACCOUNT_ALREADY_EXIST.getMessage());
        }
        Department department = departmentMapper.selectById(departmentId);
        if (department==null){
            throw new BusinessException(ResultCode.DEPARTMENT_NOT_EXIST.getCode(),
                    ResultCode.USER_ACCOUNT_NOT_EXIST.getMessage());
        }
        String salt= UUID.randomUUID().toString().substring(0,32);
        user.setSalt(salt);
        //使用mybatis-plus的自动填充功能实现
//        user.setCreateTime(new Date());
//        user.setModifiedTime(new Date());
        //使用spring security 自带的密码加密策略
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        //用户类型
        user.setType(UserTypeEnum.SYSTEM_USER.getTypeCode());
        //设置状态
        user.setStatus(UserStatusEnum.AVAILABLE.getStatusCode());
        //设置是否删除
        user.setDeleted(false);
        this.baseMapper.insert(user);
    }

    @Override
    public void exportUserExcel(HttpServletResponse response, QueryWrapper<User> wrapper) throws IOException {
        List<User> users=this.baseMapper.exportList(wrapper);
        //---写入excel文件
        String exportFileName="TbUserInfo.xlsx";
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/vnd.ms-excel");
        response.addHeader("Content-Disposition", "attachment;filename=" + exportFileName);
        EasyExcel.write(response.getOutputStream(),User.class)
                .sheet("用户信息")
                //自动列宽
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .doWrite(users);
    }

    @Override
    public void update(UserEditVO userEditVO) {
        User user=this.baseMapper.selectById(userEditVO.getId());
        if (user==null){
            throw new BusinessException(ResultCode.USER_ACCOUNT_NOT_EXIST.getCode(),
                    ResultCode.DEPARTMENT_NOT_EXIST.getMessage());
        }
        String username=userEditVO.getUsername();
        Long departmentId=userEditVO.getDepartmentId();
        QueryWrapper<User> wrapper=new QueryWrapper<>();
        wrapper.eq("username",username).ne("id",userEditVO.getId());//eq:等于 ne:不等于 <>
        Integer count=this.baseMapper.selectCount(wrapper);
        if (count!=0){
            throw new BusinessException(ResultCode.USER_ACCOUNT_USENAME_EXIST.getCode(),
                    ResultCode.USER_ACCOUNT_USENAME_EXIST.getMessage());
        }
        Department department=departmentMapper.selectById(departmentId);
        if (department==null){
            throw new BusinessException(ResultCode.DEPARTMENT_NOT_EXIST.getCode(),
                    ResultCode.USER_ACCOUNT_NOT_EXIST.getMessage());
        }
        User users=new User();
        BeanUtils.copyProperties(userEditVO,users);
        users.setModifiedTime(new Date());
        this.baseMapper.updateById(users);
    }

    @Override
    public UserEditVO edit(Long id) {
        User user =this.baseMapper.selectById(id);
        if (user==null){
            throw new BusinessException(ResultCode.USER_ACCOUNT_USE_NOT_EXIST.getCode(),
                    ResultCode.USER_ACCOUNT_USE_NOT_EXIST.getMessage());
        }
        UserEditVO userEditVO=new UserEditVO();
        BeanUtils.copyProperties(user,userEditVO);
        return userEditVO;
    }

    @Override
    public void deleteById(Long id) {
        this.baseMapper.deleteById(id);
    }


    @Override
    public String login(UserLogin userLogin) {
        String token;
        String username=userLogin.getUsername();
        String password=userLogin.getPassword();
        QueryWrapper<User> wrapper =new QueryWrapper<>();
        wrapper.eq("username",username).eq("deleted",0);
        User user=this.baseMapper.selectOne(wrapper);
        if (user!=null){
            //判断密码是否正确 解密密码
            boolean result =passwordEncoder.matches(password,user.getPassword());
            if (result){
                //生成token
               token= JWTUtils.sign(username,user.getSalt());
                //把登录用户名放进redis缓存
                redisUtil.set(token,userLogin.getUsername(),86400);
                System.out.println("====登录用户名放进redis缓存[1天后自动销毁]=========");
            }else {
                throw new BusinessException(ResultCode.USER_CREDENTIALS_ERROR.getCode(),
                        ResultCode.USER_CREDENTIALS_ERROR.getMessage());
            }

        }else {
            throw new BusinessException(ResultCode.USER_ACCOUNT_USE_NOT_EXIST.getCode(),
                    ResultCode.USER_ACCOUNT_USE_NOT_EXIST.getMessage());
        }
        return token;
    }

    @Override
    public UserInfoVO userInfo(String username) throws SystemException {
        QueryWrapper<User> wrapper =new QueryWrapper<>();
        wrapper.eq("username",username).eq("deleted",0);
        //更具用户名查询用户信息
        User user=this.baseMapper.selectOne(wrapper);
        UserInfoVO userInfoVO=new UserInfoVO();
        userInfoVO.setId(user.getId());
        userInfoVO.setUsername(user.getUsername());
        userInfoVO.setNickname(user.getNickname());
        userInfoVO.setEmail(user.getEmail());
        userInfoVO.setAvatar(user.getAvatar());
        userInfoVO.setPhoneNumber(user.getPhoneNumber());
        userInfoVO.setStatus(user.getStatus());
        userInfoVO.setCreateTime(user.getCreateTime());
        userInfoVO.setModifiedTime(user.getModifiedTime());
        userInfoVO.setSex(user.getSex());
        userInfoVO.setDepartment(user.getDepartmentId());
        userInfoVO.setType(user.getType());

        //根据用户id获取角色id
        QueryWrapper<UserRole> wrapper2=new QueryWrapper<>();
        wrapper2.eq("user_id",user.getId());
        UserRole userRole=userRoleMapper.selectOne(wrapper2);
        //根据角色id查询角色信息
        QueryWrapper<Role> wrapper3 =new QueryWrapper<>();
        wrapper3.eq("id",userRole.getRoleId());
        List<Role> roles= roleMapper.selectList(wrapper3);
        userInfoVO.setRoles(roles);

        //查询菜单表信息
        QueryWrapper<Menu> wrapper1=new QueryWrapper<>();
        wrapper1.eq("trm.role_id",userRole.getRoleId()).eq("tm.available",1);
        List<Menu> menus=menuMapper.getMenuByRoleId(wrapper1);
        userInfoVO.setMenus(menus);
        //将菜单表中得url和perm放入用户登录信息表中
        if(!CollectionUtils.isEmpty(menus)){
            Set<String> urls=new HashSet<>();
            Set<String> perms=new HashSet<>();
            for (Menu menu:menus){
                urls.add(menu.getUrl());
                perms.add(menu.getPerms());
            }
            userInfoVO.setUrls(urls);
            userInfoVO.setPerms(perms);
        }
        return userInfoVO;
    }

    @Override
    public void bindUserRole(UserRole userRole) {
        QueryWrapper<UserRole> wrapper =new QueryWrapper<>();
        wrapper.eq("user_id",userRole.getUserId());
        Integer count =userRoleMapper.selectCount(wrapper);
        if (count==0){
            userRoleMapper.insert(userRole);
        }else {
            UserRole userRole1=new UserRole();
            userRole1.setRoleId(userRole.getRoleId());
            userRoleMapper.update(userRole1,wrapper);
        }
    }


//    @Override
//    public void exportUserExcel(HttpServletResponse response, List<User> users) throws IOException {
//        //---写入excel文件
//        String exportFileName="TbUserInfo.xlsx";
//        response.setCharacterEncoding("UTF-8");
//        response.setContentType("application/vnd.ms-excel");
//        response.addHeader("Content-Disposition", "attachment;filename=" + exportFileName);
//        EasyExcel.write(response.getOutputStream(),User.class)
//                .sheet("用户信息")
//                //自动列宽

//                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
//                .doWrite(users);
//    }


}
